package dfl.bysj.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import dfl.bysj.config.RedisKey;
import dfl.bysj.config.model.VO.UserDto;
import dfl.bysj.entity.HonestGrade;
import dfl.bysj.entity.HonestStudent;
import dfl.bysj.entity.UserTeacherStudent;
import dfl.bysj.exception.Assert;
import dfl.bysj.exception.UnifiedException;
import dfl.bysj.mapper.HonestStudentMapper;
import dfl.bysj.result.ResponseEnum;
import dfl.bysj.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author DFL
 * @since 2022-04-26
 */
@Slf4j
@Service
public class HonestStudentServiceImpl extends ServiceImpl<HonestStudentMapper, HonestStudent> implements HonestStudentService {

    private HonestStudentMapper honestStudentMapper;
    private StudentService studentService;

    private RedisTemplate redisTemplate;

    private HonestGradeService honestGradeService;

    private UserTeacherStudentService userTeacherStudentService;


    private HonestService honestService;

    @Autowired
    public void setHonestService(HonestService honestService) {
        this.honestService = honestService;
    }

    @Autowired
    public void setHonestStudentMapper(HonestStudentMapper honestStudentMapper) {
        this.honestStudentMapper = honestStudentMapper;
    }

    @Autowired
    public void setHonestGradeService(HonestGradeService honestGradeService) {
        this.honestGradeService = honestGradeService;
    }

    @Autowired
    public void setUserTeacherStudentService(UserTeacherStudentService userTeacherStudentService) {
        this.userTeacherStudentService = userTeacherStudentService;
    }

    @Autowired
    public void setRedisTemplate(RedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    @Autowired
    public void setStudentService(StudentService studentService) {
        this.studentService = studentService;
    }

    /**
     * 检查学生的信用情况
     * 1、获取学生的当前分数
     * 2、通过分数、以及相应处罚记录判断学生是否正在处罚
     * 3、正在处罚，就返回异常信息
     *
     * @param token
     */
    @Override
    public void getHonestByToken(String token) {
        UserDto userDto = (UserDto) redisTemplate.opsForValue().get(RedisKey.TOKEN + token);

        Assert.notNull(userDto, ResponseEnum.TOKEN_HAS_OVERTIME);
        UserTeacherStudent userTeacherStudent = userTeacherStudentService.getOne(
                new QueryWrapper<UserTeacherStudent>()
                        .eq("use_id", userDto.getUser().getId())
                        .eq("stu_id", userDto.getStudent().getStuId())
                        .eq("check_state", 1));

        //统计记录
        //1、在一个月内的事件记录
        //2、查看成绩：如果x==95,记录==1——>说明有过惩罚，允许预约
        //           如果x==95,记录==0——>说明正在惩罚，不允许预约,查询惩罚剩余时间
        //           如果x==90，记录==1——>说明正在惩罚，不允许预约,查询惩罚剩余时间
        //           如果x==90，记录==2——>说明有过惩罚，允许预约
        //           如果x<90,不允许预约，返回下个月才能预约
        HonestGrade honestGrade = honestGradeService.getHonestGradeByStuUseId(userTeacherStudent.getStuUseId());
        if (honestGrade!=null){
            gradeCheck(honestGrade);
        }else{

        }


    }

    /**
     * 新增违规记录
     * 修改信用分数
     * 返回信用分数，如果需要处罚，则返回处罚信息
     *
     * @param
     * @param i
     * @return
     */
    @Override
    public HonestGrade insertHonestStudent(Integer stuUseId, int i) {
        HonestStudent honestStudent = new HonestStudent();
        honestStudent.setHonId(i);
        honestStudent.setStuUseId(stuUseId);
        //新增了记录
        honestStudentMapper.insert(honestStudent);
        //获取行为对应分数
        Float reduce = honestService.getGradeByHonId(i);
        log.info("reduce:"+reduce);
        //修改信用分
        HonestGrade grade = honestGradeService.updateHonestGradeByHonestStudent(stuUseId, reduce);
        gradeCheck(grade);
        return grade;
    }

    @Override
    public List<HonestStudent> getHonestsByHonId(Integer hon_id, Integer stu_use_id) {
        return honestStudentMapper.selectList(new QueryWrapper<HonestStudent>()
                .eq("stu_use_id", stu_use_id)
                .eq("hon_id", hon_id)
                .orderByDesc("update_time"));
    }



    /**
     * 获取惩罚的剩余时间，抛出异常
     * 1、获取成绩关系表的最新一条记录
     * 2、最新一条记录，必然使得分数达到95的那一条
     * 3、获取该记录的创造时间，从而计算解封时间
     *
     *
     * 加上处罚是否完成
     */
    private void checkHonset(Integer stuUseId, Long days) {
        HonestStudent honestStudent = getOne(new QueryWrapper<HonestStudent>()
                .orderByDesc("create_time")
                .eq("stu_use_id", stuUseId)
                .last("limit 1"));
        LocalDateTime localDateTime = honestStudent.getCreateTime().plusDays(days);

        LocalDateTime now=LocalDateTime.now();
        if (now.isAfter(localDateTime)){
            //说明处罚时间已经过去
            //修改记录
            honestGradeService.updateHonestRecordByStuUseId(stuUseId);
        }else{
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");
            String dateStr = formatter.format(localDateTime);
            throw new UnifiedException("您正处于信用处罚中，您将可以在" + dateStr + "后允许预约");
        }



    }

    private void gradeCheck(HonestGrade honestGrade) {
        float grade = honestGrade.getGrade();
        int recored = honestGrade.getRecord();

        if (grade == 95) {
            if (recored != 1) checkHonset(honestGrade.getStuUseId(), 3L);
        } else if (grade == 90) {
            if (recored != 2) checkHonset(honestGrade.getStuUseId(), 3L);
        } else if(grade<85){
            checkHonset(honestGrade.getStuUseId(), 30L);
        }

    }

}
